using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using System.Security;
using System.Security.Permissions;
using System.IO;
using System.Reflection;
using System.Collections;
using System.Collections.ObjectModel;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint.Security;
using Microsoft.SharePoint.Utilities;

namespace DebugConfigFeature
{

    /// <summary>
    /// A Feature Reciever for DebugConfigFeature
    /// Original sample  : http://www.codeplex.com/sharepointajax
    /// (Daniel Larson & Tony Bierman)
    /// </summary>
    [PermissionSet(SecurityAction.Demand)]
    public sealed class FeatureReceiver : SPFeatureReceiver
    {

        private const string OwnerModif = "DebugConfigFeature";

        private string UrlBp = string.Empty;

        [SharePointPermission(SecurityAction.LinkDemand, ObjectModel = true)]
        public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
        {
            //LoadProperties(properties);
            

            bool removeModification = true;
            AddOrRemoveHandler(properties, removeModification);
        }

        /// <summary>
        /// Handles the Feature Activation
        /// </summary>
        /// <param name="properties">SPFeatureReceiverProperties passes in the "context" 
        /// including the web application reference</param>
        [SharePointPermission(SecurityAction.LinkDemand, ObjectModel = true)]
        public override void FeatureActivated(SPFeatureReceiverProperties properties)
        {
            //LoadProperties(properties);

            bool removeModification = false;
            AddOrRemoveHandler(properties, removeModification);
        }

        [SharePointPermission(SecurityAction.LinkDemand, ObjectModel = true)]
        public override void FeatureInstalled(SPFeatureReceiverProperties properties)
        {
            // throw new Exception("The method or operation is not implemented.");
        }

        [SharePointPermission(SecurityAction.LinkDemand, ObjectModel = true)]
        public override void FeatureUninstalling(SPFeatureReceiverProperties properties)
        {
            // throw new Exception("The method or operation is not implemented.");
        }

        private void AddOrRemoveHandler(SPFeatureReceiverProperties properties, bool removeModification)
        {
            if (properties == null)
                throw new ArgumentNullException("properties");
            SPWebApplication app = properties.Feature.Parent as SPWebApplication;

            if (!removeModification)
                AddConfigurationToWebConfig(app, removeModification);
            else
                RemoveWebConfigEntries(app, OwnerModif);

            app.Update();
        }

        /// <summary>
        /// Adds the Orcas configuration to the web.config. 
        /// </summary>
        /// <param name="app"></param>
        /// <param name="removeModification"></param>
        /// <remarks>
        /// Tip o' the hat to Tony Bierman, 
        /// http://sharepointsolutions.blogspot.com/2006/12/using-spwebconfigmodificat_116736917110571614.html
        /// </remarks>
        public void AddConfigurationToWebConfig(SPWebApplication app, bool removeModification)
        {
            List<SPWebConfigModification> lstModifs = new List<SPWebConfigModification>();

            #region Disable Custom Errors and Enable Debugging And Stack Trace In WSS 
         
            ///Add sub nodes with values
            lstModifs.Add(GetSPWebModifAttribut(
                "CallStack",
                "configuration/SharePoint/SafeMode",
                @"true"
                ));

            lstModifs.Add(GetSPWebModifAttribut(
                "mode",
                "configuration/system.web/customErrors",
                @"Off"
                ));

            lstModifs.Add(GetSPWebModifAttribut(
                "debug",
                "configuration/system.web/compilation",
                @"true"
                ));


            //Add the modif
            foreach (SPWebConfigModification mod in lstModifs)
            {
                app.WebConfigModifications.Add(mod);
            }

            lstModifs.Clear();

            SPFarm.Local.Services.GetValue<SPWebService>().ApplyWebConfigModifications();
            #endregion


        }

        private SPWebConfigModification GetSPWebModifChild(string name, string xpath, string Nodetext)
        {
            SPWebConfigModification ModScriptResource = new SPWebConfigModification(
                 name,
                 xpath);
            ModScriptResource.Owner = OwnerModif;
            ModScriptResource.Sequence = 0;
            ModScriptResource.Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode;
            ModScriptResource.Value = Nodetext;
            return ModScriptResource;
        }

        private SPWebConfigModification GetSPWebModifSection(string name, string xpath)
        {
            SPWebConfigModification ModScriptResource = new SPWebConfigModification(
                 name,
                 xpath);
            ModScriptResource.Owner = OwnerModif;
            ModScriptResource.Sequence = 0;
            ModScriptResource.Type = SPWebConfigModification.SPWebConfigModificationType.EnsureSection;
            return ModScriptResource;
        }

        private SPWebConfigModification GetSPWebModifAttribut(string name, string xpath,string value)
        {
            SPWebConfigModification ModScriptResource = new SPWebConfigModification(
                 name,
                 xpath);
            ModScriptResource.Owner = OwnerModif;
            ModScriptResource.Sequence = 0;
            ModScriptResource.Type = SPWebConfigModification.SPWebConfigModificationType.EnsureAttribute;
            ModScriptResource.Value = value;
            return ModScriptResource;
        }

        /// <summary>
        /// Removes the web config entries.
        /// </summary>
        /// <param name="oWebApp">The o web app.</param>
        /// <param name="owner">The owner.</param>
        /// <remarks>
        /// Tips from Vincent Rothwell 
        /// http://blog.thekid.me.uk/archive/2007/03/20/removing-web-config-entries-from-sharepoint-using-spwebconfigmodification.aspx
        /// </remarks>
        private void RemoveWebConfigEntries(SPWebApplication oWebApp, string owner)
        {

            Collection<SPWebConfigModification> oCollection = oWebApp.WebConfigModifications;
            int iStartCount = oCollection.Count;
            for (int c = iStartCount - 1; c >= 0; c--)
            {
                SPWebConfigModification oModification = oCollection[c];
                if (oModification.Owner == owner)
                    oCollection.Remove(oModification);
            }

            if (iStartCount > oCollection.Count)
            {
                oWebApp.Update();
                SPFarm.Local.Services.GetValue<SPWebService>().ApplyWebConfigModifications();
            }

        }

        
    }
}